package com.tfd.blog.filter;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import static com.tfd.blog.controller.IndexController.BLOG_SESSION;

/**
 * @since TangFD@HF 2019/8/7.
 */
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Cookie session = getSession(request);
        String sessionId = null;
        if (session != null) {
            sessionId = session.getValue();
            String id = stringRedisTemplate.opsForValue().get(BLOG_SESSION);
            if (StringUtils.isNotEmpty(sessionId) && sessionId.equals(id)) {
                stringRedisTemplate.opsForValue().set(BLOG_SESSION, sessionId, 30, TimeUnit.MINUTES);
            }
        }

        NeedLogin login = method.getAnnotation(NeedLogin.class);
        if (login == null) {
            return true;
        }

        if (StringUtils.isEmpty(sessionId)) {
            return false;
        }

        String id = stringRedisTemplate.opsForValue().get(BLOG_SESSION);
        return sessionId.equals(id);
    }

    private Cookie getSession(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (ArrayUtils.isEmpty(cookies)) {
            return null;
        }

        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if (BLOG_SESSION.equals(name)) {
                return cookie;
            }
        }

        return null;
    }
}
